package com.ply.utils.encoding;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @author XiaoPan
 * date: 2022/1/4 17:48
 * <p>
 * action: base64编码 的 转换
 */
public class Base64 {
    private static final char[] BASE64 = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
            'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '+', '/'
    };

    public static void main(String[] args) {
        String a = "测试卡次数45";
        char[] chars = stringToBase64(a);
        String s = String.valueOf(chars);

        System.out.println(s);


        byte[] bytes = baseToString(s);

        String s1 = new String(bytes, StandardCharsets.UTF_8);
        System.out.println(s1);


    }
    public static String getUtf8(String str){
        String s = "";
        try{

            byte[] bytes = baseToString(str);
            s = new String(bytes, StandardCharsets.UTF_8);
        }catch (Exception e){
            e.printStackTrace();
        }
        return s;
    }


    public static String getBase64(String str){
        char[] chars = stringToBase64(str);
        return String.valueOf(chars);
    }



    /**
     * 将转成 base64编码  返回 字符数组
     *
     * @param str 正常字符串
     * @return 返回char
     */

    private static char[] stringToBase64(String str) {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);


        if (bytes.length % 3 == 1) {
            // 数组
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 2);

            char[] ppp = ppp(arr2);

            ppp[ppp.length - 2] = '=';
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        if (bytes.length % 3 == 2) {
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 1);
            char[] ppp = ppp(arr2);
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        return ppp(bytes);
    }

    public static char[] ppp(byte[] bytes) {
        int k = 0;
        int p = 0;
        char[] oo = new char[bytes.length / 3 * 4];
        while (k < oo.length) {
//            int i = ((bytes[0] << 16) | (bytes[1] << 8) | (bytes[2]));
            int i = (((bytes[p] & 0xFF) << 16) |
                    ((bytes[p + 1] & 0xFF) << 8) |
                    (bytes[p + 2] & 0xFF));

            int d3 = i & 0x3F;
            int d2 = i >>> 6 & 0x3F;
            int d1 = i >>> 12 & 0x3F;
            int d0 = i >>> 18 & 0x3F;

            oo[k] = BASE64[d0];
            oo[k + 1] = BASE64[d1];
            oo[k + 2] = BASE64[d2];
            oo[k + 3] = BASE64[d3];
            p = p + 3;
            k = k + 4;
        }

        return oo;
    }


    public static byte[] baseToString(String base64) {
        char[] chars = base64.toCharArray();


        byte[] bytes = new byte[(base64.length() / 4 * 3)];

        int bytesI = 0;
        int d0 = 0;
        int d1 = 0;
        int d2 = 0;
        int d3 = 0;
        for (int i = 0; i < chars.length; i += 4) {
            for (int j = 0; j < 64; j++) {
                if (chars[i] == BASE64[j]) d0 = j;
                if (chars[i + 1] == BASE64[j]) d1 = j;
                if (chars[i + 2] == BASE64[j]) d2 = j;
                if (chars[i + 3] == BASE64[j]) d3 = j;
            }


            int v = d3 | d2 << 6 | d1 << 12 | d0 << 18;

            bytes[bytesI] = (byte) (v >> 16 & 0xFF);

//            if (!(ys == 2 && (i == chars.length - 1)))
                bytes[bytesI + 1] = (byte) (v >> 8 & 0xFF);
//            if (!(ys >= 1 && (i == chars.length - 1)))
                bytes[bytesI + 2] = (byte) (v & 0xFF);

            bytesI += 3;
        }


        if (chars[chars.length - 1] == '=') {
            if (chars[chars.length - 2] == '=') {
                byte[] bytes1 = new byte[bytes.length - 2];
                System.arraycopy(bytes, 0, bytes1, 0, bytes1.length);
                return bytes1;
            }
            byte[] bytes1 = new byte[bytes.length - 1];
            System.arraycopy(bytes, 0, bytes1, 0, bytes1.length);
            return bytes1;

        }
        return bytes;
    }


}

